A computer system may include one or more peripheral devices, which may take the form of an add-in adapter, such as a network interface card (NIC), a local area network (LAN) on motherboard, or an integrated chipset. Programs running on such a computer system generally utilize a device driver to access the various peripheral devices, as well as other systems and components. A device driver is a program or piece of code that controls a peripheral device, and the peripheral device may have its own set of specialized commands that the corresponding driver is uniquely configured to recognize. Most programs, however, access peripheral devices using a generic set of commands, and a device's driver accepts these generic commands from a program and translates the generic commands into specialized commands for the device. Tasks performed by a driver include, by way of example, executing data input and output (I/O) operations, carrying out error processing required by a device, and processing interrupts.
Thus, interrupt processing is a function which may be performed by a driver. Most peripheral devices coupled to a computer system generate an interrupt when they need some form of attention from a Central Processing Unit (CPU) or processor. This interrupt is usually an asynchronous event that suspends normal processing of the CPU. For instance, a network controller might interrupt to indicate reception of a new packet, or to indicate the successful transmission of an outgoing packet. Legacy devices generate interrupts by asserting an “interrupt line”, which alerts the host processor to the interrupt; newer devices may use a “Message-Signaled Interrupt” instead.
A Message-Signaled Interrupt (MSI) is a mechanism for generating an interrupt in which the interrupting device writes a predetermined value (i.e., a “message”) to a predetermined address in host memory. For example, a network controller might write a special “packet received” message to memory upon receipt of an incoming packet. The MSI value and address are unique to each device; while two devices may write to the same address, these two devices would not present the same message data for the interrupt, and thus, no two devices will share exactly the same message. In other words, the combination of address and message data are unique. Of course, a single device may identify any one of several different events within a message, also ensuring that every message will be unique.
FIG. 1 is a flow diagram for an exemplary prior art interrupt handling scheme. It should be noted that, regardless of which particular interrupt mechanism is used, conventional interrupt-handling schemes usually operate in the manner illustrated. Thus, driver documentation and samples (e.g., the Microsoft Device Driver Kit, and publicly-available driver development texts) describe and implement interrupt-handling procedures as a sequential series of steps, neglecting the inherent parallelism of their host devices. Thus, over a period of time 110, some event will occur at block 112, and a device will generate an associated hardware interrupt at block 114. After the computer system connected to the device recognizes the interrupt, the operating system schedules an interrupt handler to process the interrupt, in response to the interrupting event at block 116.
As mentioned previously, the interrupt handler operates in the form of a single, serial thread of execution. The single, monolithic handler thus processes multiple interrupting events in turn, as shown at blocks 118, 120, and 122. “Later” events are not processed until “earlier” events have been accommodated, increasing the average latency 124 associated with the “nth” event.